using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using Microsoft.SoftwarePlusServices.ReferenceBits.OutlookPlusServices;
using System.Timers;

namespace Microsoft.SoftwarePlusServices.ReferenceBits.OutlookPlusServices
{
    ///
    /// <summary>
    /// When implementing Software + Services applications one often wants to have one or more
    /// "background" processes that update statuses at various time intervals.
    /// 
    /// This base class supports the implementation of a timer-based "task"
    ///
    /// To use this object, extended it an implement the PerformUpdate() method
    /// </summary>
    /// 
    public class Scheduler : IScheduler
    {
        /// <summary>
        /// Each Scheduler requires a timer and a time interval
        /// </summary>

        #region Private Fields
        private System.Timers.Timer _checkTimer = new System.Timers.Timer();
        private int _intervalSeconds = -1;
        #endregion

        #region Constructor
        /// <summary>
        /// Creating a Scheduler 
        /// </summary>
        public Scheduler()
        {
            _checkTimer.Elapsed +=
                delegate(object s, ElapsedEventArgs e)
                {
                    UpdateNow();
                };
        }
        #endregion

        #region Public Methods

        ///
        /// <summary>
        /// Starts a timer that will cause a periodic call to the PerformUpdate method in
        /// your scheduled tasks objects
        /// </summary>
        /// <param name="intervalSeconds">The number of seconds between periodic updates.</param>
        /// 
        public void StartTimer(int intervalSeconds)
        {
            // setup the handler to fire on the check interval
            _intervalSeconds = intervalSeconds;
            _checkTimer.Interval = intervalSeconds * 1000;
            if (_intervalSeconds != -1)
                _checkTimer.Start();
        }

        ///
        /// <summary>
        /// Stops the periodic calling of the PerformUpdate method in your
        /// scheduled task objects
        /// </summary>
        /// 
        public void StopTimer()
        {
            if (_intervalSeconds != -1)
            {
                _checkTimer.Stop();
                _intervalSeconds = -1;
            }
        }
        #endregion

        #region IScheduler Members

        ///
        /// <summary>
        /// Attempts to stop the timer, then call the PerformUpdate
        /// method in your schedule task object
        /// and then restarts the timer
        /// </summary>
        /// 
        public void UpdateNow()
        {
            try
            {
                // stop the timer
                if (_intervalSeconds != -1)
                    _checkTimer.Stop();

                PerformUpdate();
            }
            finally
            {
                // restart the timer
                if (_intervalSeconds != -1)
                    _checkTimer.Start();
            }
        }

        ///
        /// <summary>
        /// Your scheduled task objects should be derived from the Scheduler
        /// class and override the PerformUpdate method where you should 
        /// </summary>
        /// 
        public virtual void PerformUpdate()
        {
        }
        #endregion

    }
}
